package com.iqiyi.pps.epg.core.service.statistic;


import com.iqiyi.kiwi.utils.Configuration;
import com.iqiyi.pps.epg.api.model.web.query.TFilter;
import com.iqiyi.pps.epg.api.model.web.query.TPage;
import com.iqiyi.pps.epg.api.model.web.statistic.TStatisticProduceData;
import com.iqiyi.pps.epg.api.model.web.statistic.TStatisticProduceDataPage;
import com.iqiyi.pps.epg.core.dao.statistic.StatisticProduceDataDao;
import com.iqiyi.pps.epg.core.model.statistic.StatisticProduceData;
import com.iqiyi.pps.epg.core.utils.DateTimeUtil;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hibernate.type.StringType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;


@Service
@Transactional
public class StatisticServiceImpl implements StatisticService {

    public static Logger logger = LoggerFactory.getLogger(StatisticServiceImpl.class);

    @Autowired
    StatisticProduceDataDao statisticProduceDataDao;

    public static boolean isProductionEnv() {
        return "production".equals(Configuration.getString("deploy.env"));
    }

    @Override
    public void saveProduceData(StatisticProduceData entity) {
        statisticProduceDataDao.save(entity);
    }

    @Override
    public StatisticProduceData getProduceData(long id) {
        return statisticProduceDataDao.get(id);
    }

    //    @Override
//    @Transactional(propagation = Propagation.NOT_SUPPORTED)
//    public List<StatisticProduceData> getCrontabProduceData() {
//        Calendar calendar = Calendar.getInstance();
//        calendar.set(Calendar.HOUR_OF_DAY, 0);
//        calendar.set(Calendar.MINUTE, 0);
//        calendar.set(Calendar.SECOND, 0);
//        calendar.set(Calendar.MILLISECOND, 0);
//        calendar.add(Calendar.DATE, isProductionEnv() ? -3 : -1);  //只会查询三天前
//        Timestamp ts = new Timestamp(calendar.getTimeInMillis());
//
//        Criteria criteria = statisticProduceDataDao.createCriteria();
//        criteria.add(Restrictions.ne("isCallLego", 1));
//        criteria.add(Restrictions.ge("addTime", ts));
//        List<StatisticProduceData> data = statisticProduceDataDao.find(criteria);
//        return data;
//    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<StatisticProduceData> getCrontabProduceData() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.add(Calendar.DATE, isProductionEnv() ? -3 : -1);  //只会查询三天前
        Timestamp ts = new Timestamp(calendar.getTimeInMillis());

        Criteria criteria = statisticProduceDataDao.createCriteria();
        criteria.add(Restrictions.or(Restrictions.ne("isCallLego", 1), Restrictions.and(Restrictions.eq("isCallLego", 1), Restrictions.eq("legoProduceFinishedTime", 2))));
        criteria.add(Restrictions.ge("addTime", ts));
        List<StatisticProduceData> data = statisticProduceDataDao.find(criteria);
        return data;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public TStatisticProduceDataPage getProduceData(TPage page, TFilter filter) {

        TStatisticProduceDataPage spdList = new TStatisticProduceDataPage();

        try {

            long startTime = System.currentTimeMillis();
            String countSql = "SELECT COUNT(*) AS total " +
                    "FROM st_produce_data  WHERE 1 ";
            String listSql = "SELECT * FROM st_produce_data where 1";

            String sql = "";

            if (filter.getFilters().containsKey("program_id")) {
                sql += " AND program_id = " + filter.getFilters().get("program_id");
            }
            if (filter.getFilters().containsKey("bDate")) {
                sql += " AND add_time >= '" + Timestamp.valueOf(filter.getFilters().get("bDate")) + "'";
            }
            if (filter.getFilters().containsKey("eDate")) {
                sql += " AND add_time <= '" + Timestamp.valueOf(filter.getFilters().get("eDate")) + "'";
            }

            String sql1 = null;
            String sql2 = null;
            if (filter.getFilters().containsKey("live_b_date")) {
                sql1 = " live_end_time >= '" + filter.getFilters().get("live_b_date") + "' ";
            }
            if (filter.getFilters().containsKey("live_e_date")) {
                sql2 = " live_begin_time <= '" + filter.getFilters().get("live_e_date") + "' ";
            }

            if (sql1 != null) {
                sql += " and " + sql1;
            }
            if (sql2 != null) {
                sql += " and " + sql2;
            }

            if (filter.getFilters().containsKey("ocr_flag")) {
                sql += " AND ocr_flag = " + filter.getFilters().get("ocr_flag");
            }

            if (filter.getFilters().containsKey("ocr_title_flag")) {
                sql += " AND ocr_title_flag = " + filter.getFilters().get("ocr_title_flag");
            }

            if (filter.getFilters().containsKey("prName")) {
                sql += " AND program_name like '%" + filter.getFilters().get("prName") + "%'";
            }

            if (filter.getFilters().containsKey("sPrMins")) {
                sql += " AND program_minutes >= " + Float.valueOf(filter.getFilters().get("sPrMins"));
            }
            if (filter.getFilters().containsKey("ePrMins")) {
                sql += " AND program_minutes <= " + Float.valueOf(filter.getFilters().get("ePrMins"));
            }

            if (filter.getFilters().containsKey("cName")) {
                sql += " AND channel_name like '%" + filter.getFilters().get("cName") + "%'";
            }
            if (filter.getFilters().containsKey("u")) {
                sql += " AND user = '" + filter.getFilters().get("u") + "'";
            }
            if (filter.getFilters().containsKey("cp")) {
                sql += " AND cooperative_partiner = '" + filter.getFilters().get("cp") + "'";
            }
            if (filter.getFilters().containsKey("bt")) {
                sql += " AND live_begin_time = '" + Timestamp.valueOf(filter.getFilters().get("bt")) + "'";
            }
            if (filter.getFilters().containsKey("et")) {
                sql += " AND live_end_time = '" + Timestamp.valueOf(filter.getFilters().get("et")) + "'";
            }

            if (filter.getFilters().containsKey("albumName")) {
                sql += " AND album_name like '%" + filter.getFilters().get("albumName") + "%'";
            }

            if (StringUtils.isBlank(sql)) {
                Calendar calendar = Calendar.getInstance();
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                calendar.add(Calendar.DATE, +1);

                sql += " AND add_time< '" + new Timestamp(calendar.getTimeInMillis()) + "'";
                calendar.add(Calendar.DATE, -7);
                sql += " AND add_time>= '" + new Timestamp(calendar.getTimeInMillis()) + "'";
                logger.info("sql:{}", sql);
            }


            String totalCount = statisticProduceDataDao.getSession().createSQLQuery(countSql + sql).addScalar("total", new StringType()).list().get(0).toString();

            sql += "  ORDER BY id DESC LIMIT " + (page.getPageNo() - 1) * page.getPageSize() + " , " + page.getPageSize();
            logger.info("[StatisitcServiceImpl][sql]: {}", listSql + sql);
            List<StatisticProduceData> result = statisticProduceDataDao.getSession().createSQLQuery(listSql + sql).addEntity(StatisticProduceData.class).list();

            List<TStatisticProduceData> tspdList = new ArrayList();
            long ctime = System.currentTimeMillis();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (StatisticProduceData single : result) {
                TStatisticProduceData tSPD = new TStatisticProduceData();

                tSPD.setId(single.getId());
                tSPD.setProgramId(single.getProgramId());
                if (single.getQipuId() != null)
                    tSPD.setQipuId(single.getQipuId());
                tSPD.setProgramName(single.getProgramName());
                tSPD.setProgramMinutes(String.valueOf(single.getProgramMinutes()));
                tSPD.setChannelName(single.getChannelName());
                tSPD.setUser(single.getUser());
                tSPD.setCooperativePartiner(single.getCooperativePartiner());
                if (single.getProduceDate() != null)
                    tSPD.setProduceDate(single.getProduceDate());
                if (single.getDotSubTime() != null)
                    tSPD.setDotSubTime(sdf.format(single.getDotSubTime()));
                if (single.getEnterLegoTime() != null)
                    tSPD.setEnterLegoTime(sdf.format(single.getEnterLegoTime()));
                if (single.getLegoProduceFinishedTime() != null)
                    tSPD.setLegoProduceFinishedTime(String.valueOf(single.getLegoProduceFinishedTime()));
                if (single.getPublishTime() != null)
                    tSPD.setPublishTime(sdf.format(single.getPublishTime()));
                if (single.getLiveBeginTime() != null)
                    tSPD.setLiveBeginTime(sdf.format(single.getLiveBeginTime()));
                if (single.getLiveEndTime() != null)
                    tSPD.setLiveEndTime(sdf.format(single.getLiveEndTime()));
                if (single.getAddTime() != null)
                    tSPD.setAddTime(sdf.format(single.getAddTime()));
                if (single.getStartAutoDot() != null)
                    tSPD.setStartAutoDot(single.getStartAutoDot());
                if (single.getStartManualDot() != null)
                    tSPD.setStartManualDot(single.getStartManualDot());
                if (single.getEndAutoDot() != null)
                    tSPD.setEndAutoDot(single.getEndAutoDot());
                if (single.getEndManualDot() != null)
                    tSPD.setEndManualDot(single.getEndManualDot());
                if (single.getAdInfo() != null)
                    tSPD.setAdInfo(single.getAdInfo());
                if (single.getAlbumName() != null)
                    tSPD.setAlbumName(single.getAlbumName());

                if (single.getIntelligentInsertTime() != null) {
                    tSPD.setIntelligentInsertTime(sdf.format(single.getIntelligentInsertTime()));
                }
                tSPD.setOcrFlag(single.getOcrFlag());
                tSPD.setOcrTitleFlag(single.getOcrTitleFlag());
                tSPD.setDataMode( single.getDataMode());
                tspdList.add(tSPD);
            }
            spdList.setResult(tspdList);
            page.setTotalCount(Long.valueOf(totalCount));
            spdList.setTPage(page);
            logger.info("[StatisitcServiceImpl]time: {} data{}", System.currentTimeMillis() - startTime, spdList);
        } catch (Exception e) {
            logger.error("[StatisitcServiceImpl][getProduceData][exception=]", e);
        }
        return spdList;
    }

    @Override
    public void updateProduceData(Long id, Map<String, String> params) {
        logger.info("[params] {}", params.toString());
        StringBuffer sb = new StringBuffer();
        boolean hasSet = false;
        String str1 = "update StatisticProduceData set ";
        String str2 = " where id = " + id;

        if (Long.valueOf(params.get("qipuId")) > 0) {
            hasSet = true;
            sb.append(" qipuId = " + params.get("qipuId") + " ,");
            sb.append(" isCallLego = 1 ,");
        }
        if (StringUtils.isNotEmpty(params.get("pageFirstPublishTime"))) {
            hasSet = true;
            sb.append(" publishTime = '" + DateTimeUtil.transLongFormat(Long.valueOf(params.get("pageFirstPublishTime"))) + "' ,");
        }
        if (StringUtils.isNotBlank(params.get("releaseStatus"))) {
            hasSet = true;
            sb.append(" legoProduceFinishedTime = " + params.get("releaseStatus") + " ,");
        }
        if (hasSet) {
            statisticProduceDataDao.createQuery(str1 + sb.deleteCharAt(sb.length() - 1).toString() + str2).executeUpdate();
        }
    }

    @Override
    public void updateEnterLegoTime(Long prid, Timestamp ts) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
            Criteria criteria = statisticProduceDataDao.createCriteria();
            Long ctm = System.currentTimeMillis();
            Integer millsOfDay = 86400 * 1000;

            String threeDayAgo = sdf.format(ctm - 3 * millsOfDay);  // 三天前
            String addOneDay = sdf.format(ctm + millsOfDay);

            // criteria.add(Restrictions.le("addTime",Timestamp.valueOf(addOneDay)));
            criteria.add(Restrictions.ge("addTime", Timestamp.valueOf(threeDayAgo)));
            criteria.add(Restrictions.eq("programId", prid));
            criteria.addOrder(Order.desc("id"));

            List<StatisticProduceData> data = statisticProduceDataDao.find(criteria);
            int executeUpdate = 0;
            for (StatisticProduceData single : data) {
                if (single.getEnterLegoTime() == null) {
                    executeUpdate = statisticProduceDataDao.createQuery("update StatisticProduceData set enterLegoTime = ? where id = ? ").setTimestamp(0, ts).setLong(1, single.getId()).executeUpdate();
                    logger.info("[updateEnterLegoTime][id={}][prid={}][updateNum={}][enterLegoTime={}]", single.getId(), prid, executeUpdate, ts);
                    break;
                }
            }

            logger.info("prid={},ts={},data.size={}", new Object[]{Long.toString(prid), ts, data.size()});
        } catch (Exception e) {
            logger.error("[StatisitcServiceImpl][updateEnterLegoTime][exception=]", e);
        }

    }

}
